#ifndef __INSN_H__
#define __INSN_H__

#include <hbird_sdk_soc.h>

#ifndef _DEBUG_INFO_
#define _DEBUG_INFO_
#endif
//nice core status register mask
#define IS_BUSY_MSK   0x00000001
#define U42A_RDY_MSK  0x00000004
#define SIGMA_RDY_MSK 0x00000002
//my general rs1 format:
//    rs1[31:0]: 1st data address in dtcm
//my general rs2 format:
//    rs2[31:8]: start address in nice core's ram
//    rs2[7 :1]: data batch size (base-2, i.e 2^n)
//    rs2[0 :0]: ram select id
#define LDBUF_CS_MSK  0x00000001
#define LDBUF_BS_MSK  0x000000fe
#define LDBUF_SA_MSK  0xffffff00

__STATIC_FORCEINLINE int custom_mrt_rdstat(int cfgbits)
{
    int reg32bits;
    
    asm volatile (
       ".insn r 0x7b, 6, 1, %0, %1, x0"
             :"=r"(reg32bits)
             :"r"(cfgbits)
     );
    
    return reg32bits;
}

__STATIC_FORCEINLINE int custom_mrt_start()
{
    int status;

    asm volatile (
       ".insn r 0x7b, 4, 2, %0, x0, x0"
             :"=r"(status)
     );

    return status;
}

// this command is obsolete and do nothing now
__STATIC_FORCEINLINE int custom_mrt_ldbuf(int addr, int cfgbits)
{
    int status;

    asm volatile (
       ".insn r 0x7b, 7, 4, %0, %1, %2"
             :"=r"(status)
			 :"r"(addr),"r"(cfgbits)
     );

    return status;
}

__STATIC_FORCEINLINE int custom_prg_rdstat(int cfgbits)
{
    int status;

    asm volatile (
       ".insn r 0x7b, 6, 5, %0, %1, x0"
             :"=r"(status)
			 :"r" (cfgbits)
     );

    return status;
}

__STATIC_FORCEINLINE int custom_prg_start(int addr, int cfgbits)
{
    int status;

    asm volatile (
       ".insn r 0x7b, 7, 6, %0, %1, %2"
             :"=r"(status)
			 :"r"(addr),"r"(cfgbits)
     );

    return status;
}

// this command is obsolete and do nothing now
__STATIC_FORCEINLINE int custom_prg_ldbuf(int addr, int cfgbits)
{
    int status;

    asm volatile (
       ".insn r 0x7b, 7, 7, %0, %1, %2"
             :"=r"(status)
			 :"r"(addr),"r"(cfgbits)
     );

    return status;
}

// nice core user function declaration
int mrt_read_status();
int mrt_is_busy();
int mrt_is_u42a_rdy();
int mrt_is_sigma_rdy();
int mrt_read_u42a();
int mrt_read_sigma();
int mrt_start();
//int mrt_load_buffer(int data[],int start_addr, int batch_size, int cs);
int prg_read_status();
int prg_is_busy();
//int prg_load_buffer(int data[],int start_addr);
int prg_start(int itcm[]);
#endif

